package com.the_last.service;

import com.the_last.config.RabbitConfig;
import com.the_last.constant.OrderConstant;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.UUID;

/**
 * 订单超时消息服务
 * 
 * @author zhanghaifeng
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class OrderTimeoutMessageService {
    
    private final RabbitTemplate rabbitTemplate;
    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    
    /**
     * 发送订单超时延迟消息
     * @param orderId 订单ID
     */
    public void sendOrderTimeoutMessage(Long orderId) {
        String currentTime = LocalDateTime.now().format(FORMATTER);
        String messageId = UUID.randomUUID().toString();
        
        log.info("[{}] 发送订单超时延迟消息", currentTime);
        log.info("订单ID: {}", orderId);
        log.info("消息ID: {}", messageId);
        log.info("超时时间: {} 分钟", OrderConstant.ORDER_TIMEOUT_MILLIS / 60000);
        
        try {
            // 设置消息属性
            MessageProperties properties = new MessageProperties();
            properties.setMessageId(messageId);
            properties.setTimestamp(new java.util.Date());
            
            // 发送订单ID到延时队列，等待TTL过期后自动转移到超时处理队列
            rabbitTemplate.convertAndSend(
                RabbitConfig.ORDER_DELAY_EXCHANGE,
                RabbitConfig.ORDER_DELAY_QUEUE,
                orderId.toString(),
                message -> {
                    message.getMessageProperties().setMessageId(messageId);
                    message.getMessageProperties().setTimestamp(new java.util.Date());
                    return message;
                }
            );
            
            log.info("订单超时延迟消息发送成功，订单ID: {}, 消息ID: {}", orderId, messageId);
            
        } catch (Exception e) {
            log.error("发送订单超时延迟消息失败，订单ID: {}", orderId, e);
            throw new RuntimeException("发送订单超时消息失败", e);
        }
    }
    
    /**
     * 直接发送消息到订单超时处理队列（用于测试）
     * @param orderId 订单ID
     */
    public void sendOrderTimeoutMessageDirectly(Long orderId) {
        String currentTime = LocalDateTime.now().format(FORMATTER);
        String messageId = UUID.randomUUID().toString();
        
        log.info("[{}] 直接发送消息到订单超时处理队列", currentTime);
        log.info("订单ID: {}", orderId);
        log.info("消息ID: {}", messageId);
        
        try {
            rabbitTemplate.convertAndSend(
                RabbitConfig.ORDER_TIMEOUT_EXCHANGE,
                RabbitConfig.ORDER_TIMEOUT_QUEUE,
                orderId.toString(),
                message -> {
                    message.getMessageProperties().setMessageId(messageId);
                    message.getMessageProperties().setTimestamp(new java.util.Date());
                    return message;
                }
            );
            
            log.info("消息发送成功到订单超时处理队列，订单ID: {}, 消息ID: {}", orderId, messageId);
            
        } catch (Exception e) {
            log.error("发送消息到订单超时处理队列失败，订单ID: {}", orderId, e);
            throw new RuntimeException("发送消息失败", e);
        }
    }
    
    /**
     * 测试发送简单消息到延时队列
     * @param message 测试消息
     */
    public void sendTestMessage(String message) {
        String currentTime = LocalDateTime.now().format(FORMATTER);
        String messageId = UUID.randomUUID().toString();
        
        log.info("[{}] 发送测试消息到延时队列: {}", currentTime, message);
        
        try {
            rabbitTemplate.convertAndSend(
                RabbitConfig.ORDER_DELAY_EXCHANGE,
                RabbitConfig.ORDER_DELAY_QUEUE,
                message,
                msg -> {
                    msg.getMessageProperties().setMessageId(messageId);
                    msg.getMessageProperties().setTimestamp(new java.util.Date());
                    return msg;
                }
            );
            
            log.info("测试消息发送成功，消息ID: {}", messageId);
            
        } catch (Exception e) {
            log.error("发送测试消息失败", e);
            throw new RuntimeException("发送测试消息失败", e);
        }
    }
}